#include "lcd_dirver.h"
#include "spi.h"
#include "tim.h"
//#include "dma.h"

uint16_t BACK_COLOR;   //背景色
static uint16_t backlight = 0;

/******************************************************************************
      函数说明：LCD串行数据写入函数
      入口数据：dat  要写入的串行数据
      返回值：  无
******************************************************************************/
void LCD_Writ_Bus(uint8_t dat)
{
    //OLED_CS_Clr();
    HAL_SPI_Transmit(&hspi3, &dat, 1, 0xffff);

    //OLED_CS_Set();
}


/******************************************************************************
      函数说明：LCD写入数据
      入口数据：dat 写入的数据
      返回值：  无
******************************************************************************/
void LCD_WR_DATA8(uint8_t dat)
{
    LCD_DC_Set();//写数据
    LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明：LCD写入数据
      入口数据：dat 写入的数据
      返回值：  无
******************************************************************************/
void LCD_WR_DATA(uint16_t dat)
{
    LCD_DC_Set();//写数据
    LCD_Writ_Bus(dat >> 8);
    LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明：LCD写入命令
      入口数据：dat 写入的命令
      返回值：  无
******************************************************************************/
void LCD_WR_REG(uint8_t dat)
{
    LCD_DC_Clr();//写命令
    LCD_Writ_Bus(dat);
}


/******************************************************************************
      函数说明：设置起始和结束地址
      入口数据：x1,x2 设置列的起始和结束地址
                y1,y2 设置行的起始和结束地址
      返回值：  无
******************************************************************************/
void LCD_Address_Set(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
    if(USE_HORIZONTAL == 0)
    {
        LCD_WR_REG(0x2a);//列地址设置
        LCD_WR_DATA(x1 + 26);
        LCD_WR_DATA(x2 + 26);
        LCD_WR_REG(0x2b);//行地址设置
        LCD_WR_DATA(y1 + 1);
        LCD_WR_DATA(y2 + 1);
        LCD_WR_REG(0x2c);//储存器写
    }
    else if(USE_HORIZONTAL == 1)
    {
        LCD_WR_REG(0x2a);//列地址设置
        LCD_WR_DATA(x1 + 26);
        LCD_WR_DATA(x2 + 26);
        LCD_WR_REG(0x2b);//行地址设置
        LCD_WR_DATA(y1 + 1);
        LCD_WR_DATA(y2 + 1);
        LCD_WR_REG(0x2c);//储存器写
    }
    else if(USE_HORIZONTAL == 2)
    {
        LCD_WR_REG(0x2a);//列地址设置
        LCD_WR_DATA(x1 + 1);
        LCD_WR_DATA(x2 + 1);
        LCD_WR_REG(0x2b);//行地址设置
        LCD_WR_DATA(y1 + 26);
        LCD_WR_DATA(y2 + 26);
        LCD_WR_REG(0x2c);//储存器写
    }
    else
    {
        LCD_WR_REG(0x2a);//列地址设置
        LCD_WR_DATA(x1 + 1);
        LCD_WR_DATA(x2 + 1);
        LCD_WR_REG(0x2b);//行地址设置
        LCD_WR_DATA(y1 + 26);
        LCD_WR_DATA(y2 + 26);
        LCD_WR_REG(0x2c);//储存器写
    }
}


/******************************************************************************
      函数说明：LCD初始化函数
      入口数据：无
      返回值：  无
******************************************************************************/
void LCD_Init(void)
{
	HAL_GPIO_WritePin(LCD_CS_GPIO_Port, LCD_CS_Pin,GPIO_PIN_RESET);
   // LL_GPIO_ResetOutputPin(LCD_CS_GPIO_Port, LCD_CS_Pin); //片选

	HAL_TIM_Base_Start(&htim4);
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1);
	
    
    LCD_RST_Clr();
    HAL_Delay(100);
    LCD_RST_Set();
    HAL_Delay(300);
//************* Start Initial Sequence **********//
    LCD_WR_REG(0x11);
//    HAL_Delay(100);
    LCD_WR_REG(0x21);

    LCD_WR_REG(0xB1);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3A);
    LCD_WR_DATA8(0x3A);

    LCD_WR_REG(0xB2);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3A);
    LCD_WR_DATA8(0x3A);

    LCD_WR_REG(0xB3);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3A);
    LCD_WR_DATA8(0x3A);
    LCD_WR_DATA8(0x05);
    LCD_WR_DATA8(0x3A);
    LCD_WR_DATA8(0x3A);

    LCD_WR_REG(0xB4);
    LCD_WR_DATA8(0x03);

    LCD_WR_REG(0xC0);
    LCD_WR_DATA8(0x62);
    LCD_WR_DATA8(0x02);
    LCD_WR_DATA8(0x04);

    LCD_WR_REG(0xC1);
    LCD_WR_DATA8(0xC0);

    LCD_WR_REG(0xC2);
    LCD_WR_DATA8(0x0D);
    LCD_WR_DATA8(0x00);

    LCD_WR_REG(0xC3);
    LCD_WR_DATA8(0x8D);
    LCD_WR_DATA8(0x6A);

    LCD_WR_REG(0xC4);
    LCD_WR_DATA8(0x8D);
    LCD_WR_DATA8(0xEE);

    LCD_WR_REG(0xC5);  /*VCOM*/
    LCD_WR_DATA8(0x0E);

    LCD_WR_REG(0xE0);
    LCD_WR_DATA8(0x10);
    LCD_WR_DATA8(0x0E);
    LCD_WR_DATA8(0x02);
    LCD_WR_DATA8(0x03);
    LCD_WR_DATA8(0x0E);
    LCD_WR_DATA8(0x07);
    LCD_WR_DATA8(0x02);
    LCD_WR_DATA8(0x07);
    LCD_WR_DATA8(0x0A);
    LCD_WR_DATA8(0x12);
    LCD_WR_DATA8(0x27);
    LCD_WR_DATA8(0x37);
    LCD_WR_DATA8(0x00);
    LCD_WR_DATA8(0x0D);
    LCD_WR_DATA8(0x0E);
    LCD_WR_DATA8(0x10);

    LCD_WR_REG(0xE1);
    LCD_WR_DATA8(0x10);
    LCD_WR_DATA8(0x0E);
    LCD_WR_DATA8(0x03);
    LCD_WR_DATA8(0x03);
    LCD_WR_DATA8(0x0F);
    LCD_WR_DATA8(0x06);
    LCD_WR_DATA8(0x02);
    LCD_WR_DATA8(0x08);
    LCD_WR_DATA8(0x0A);
    LCD_WR_DATA8(0x13);
    LCD_WR_DATA8(0x26);
    LCD_WR_DATA8(0x36);
    LCD_WR_DATA8(0x00);
    LCD_WR_DATA8(0x0D);
    LCD_WR_DATA8(0x0E);
    LCD_WR_DATA8(0x10);

    LCD_WR_REG(0x3A);
    LCD_WR_DATA8(0x05);

    LCD_WR_REG(0x36);

    if(USE_HORIZONTAL == 0)LCD_WR_DATA8(0x08);
    else if(USE_HORIZONTAL == 1)LCD_WR_DATA8(0xC8);
    else if(USE_HORIZONTAL == 2)LCD_WR_DATA8(0x78);
    else LCD_WR_DATA8(0xA8);

    LCD_WR_REG(0x29);
}


/******************************************************************************
      函数说明： LCD屏幕亮度调节
      入口数据： 占空比，0-1000 对应屏幕亮度
      返回值：   无
******************************************************************************/
void LCD_Set_Brilliance(uint16_t brilliance)
{
	__HAL_TIM_SET_COMPARE(&htim4,TIM_CHANNEL_1,brilliance);
    backlight = brilliance;
}

/******************************************************************************
      函数说明： 获得LCD屏幕亮度
      入口数据： 无
      返回值：   亮度值
******************************************************************************/
uint16_t LCD_get_Brilliance()
{
    return backlight;
}


/******************************************************************************
      函数说明：LCD清屏函数
      入口数据：无
      返回值：  无
******************************************************************************/
//void LCD_Clear(uint16_t Color)
//{
//    uint16_t i, j;
//    LCD_Address_Set(0, 0, LCD_W - 1, LCD_H - 1);

//    for(i = 0; i < LCD_W; i++)
//    {
//        for (j = 0; j < LCD_H; j++)
//        {
//            LCD_WR_DATA(Color);
//        }

//    }
//}



/******************************************************************************
      函数说明：LCD显示汉字
      入口数据：x,y   起始坐标
      返回值：  无
******************************************************************************/
//void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color)
//{
//    LCD_Address_Set(x, y, x, y); //设置光标位置
//    LCD_WR_DATA(color);
//}




/******************************************************************************
      函数说明：在指定区域填充颜色
      入口数据：xsta,ysta   起始坐标
                xend,yend   终止坐标
      返回值：  无
******************************************************************************/
//void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color)
//{
//    uint16_t i, j;
//    LCD_Address_Set(xsta, ysta, xend, yend);   //设置光标位置

//    for(i = ysta; i <= yend; i++)
//    {
//        for(j = xsta; j <= xend; j++)
//			LCD_WR_DATA(color); //设置光标位置
//    }
//}

#define LCD_BUFFER_SIZE   (80*160*2)
uint8_t LCD_Buffer[LCD_BUFFER_SIZE];


/******
* 绘制一个点
*******/
void LCD_DrawPoint(uint16_t x, uint16_t y, uint16_t color)
{
	LCD_Buffer[2 * x + 320 * y] = (color >> 8);
	LCD_Buffer[2 * x +1 + 320 * y] = (color & 0x00ff);
}


/******
* 清空屏幕
*******/
void LCD_Clear(uint16_t color)
{
	for(int i = 0; i < sizeof(LCD_Buffer); i= i + 2)
	{
		LCD_Buffer[i] = (color >> 8);
		LCD_Buffer[i + 1] = (color & 0x00ff);
	}
}


/******
* 在指定区域填充
*******/
void LCD_Fill(uint16_t xsta, uint16_t ysta, uint16_t xend, uint16_t yend, uint16_t color)
{
	for(uint16_t i = xsta; i < xend; i ++)
	{
		for(uint16_t j = ysta; j < yend; j ++)
		{
				LCD_Buffer[2 * i + 320 * j] = (color >> 8);
				LCD_Buffer[2 * i + 1 + 320 * j] = (color & 0x00ff);
		}
	}
}


/******
* 刷新
*******/

void LCD_Refresh(void)
{
	LCD_Address_Set(0, 0, LCD_W - 1, LCD_H - 1);
	LCD_DC_Set();//写数据
	HAL_SPI_Transmit_DMA(&hspi3, LCD_Buffer, sizeof(LCD_Buffer));


//	LL_DMA_SetMemoryAddress(DMA1,LL_DMA_STREAM_5,(uint32_t)LCD_Buffer);
//	LL_DMA_SetPeriphAddress(DMA1,LL_DMA_STREAM_5,(uint32_t)(&SPI3->DR));
//	LL_DMA_SetDataLength(DMA1,LL_DMA_STREAM_5,sizeof(LCD_Buffer));
//
//	LL_DMA_EnableStream(DMA1,LL_DMA_STREAM_5);
//
//	LL_SPI_EnableDMAReq_TX(SPI3);
}


#include <stdio.h>

void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
	//printf("HAL_SPI_TxRxCpltCallback");
	//HAL_GPIO_TogglePin(RUN_LED_GPIO_Port,RUN_LED_Pin);
	LCD_Refresh();
}

